package com.example.exceldemo.service.impl;

import com.example.exceldemo.entity.PoiPerson;
import com.example.exceldemo.entity.SaleDataExcelDto;
import com.example.exceldemo.service.PoiExcelService;
import com.example.exceldemo.utils.poi.v0.PoiExcelUtilsV0;
import com.example.exceldemo.utils.poi.v2.PoiExcelUtilsV2;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

/**
 * @Description
 * @Author xiaohuang
 * @Date 2024/9/10
 */
@Service
@Slf4j
public class PoiExcelServiceImpl implements PoiExcelService {
    /**
     * 自定义导出：如果是简单的导出，不建议使用，因为数据是遍历填充
     */
    @Override
    public void customExp() {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        log.info("开始执行-downloadTemplate");
        /**
         * step 0:初始化导出数据
         */
        SaleDataExcelDto d1 = new SaleDataExcelDto(1, LocalDate.now(), "A001.001", "聚美优品", BigDecimal.valueOf(55), 1, BigDecimal.valueOf(54), 1);
        SaleDataExcelDto d2 = new SaleDataExcelDto(2, LocalDate.now(), "A002.002", "聚美优品", BigDecimal.valueOf(66), 2, BigDecimal.valueOf(64), 2);
        List<SaleDataExcelDto> dataList = Arrays.asList(d1, d2);
        /**
         * step 1:初始化表格
         */
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("销售数据导入模板");
        sheet.setDefaultColumnWidth(18);
        /**
         * step 2.1:创建所需样式风格
         */
        CellStyle cellStyleHead = PoiExcelUtilsV0.cellStyleHead(workbook);
        CellStyle cellStyleCenter = PoiExcelUtilsV0.cellStyleCenter(workbook);
        CellStyle cellStyleDouble = PoiExcelUtilsV0.cellStyleDoubleCenter(workbook);
        CellStyle cellStyleDataFormat = PoiExcelUtilsV0.cellStyleDataFormat(workbook);
        CellStyle cellStyleRemarks = PoiExcelUtilsV0.cellStyleRemarks(workbook);
        /**
         * step 2.2:设置表头
         */
        Row rowHead = sheet.createRow(0);
        rowHead.setHeightInPoints(40);
        String[] head = {"序号", "日期", "ID", "品牌名称", "销售额（元）", "销售笔数（单）", "外卖销售额（元）", "外卖销售笔数（单）"};
        for (int i = 0; i < head.length; i++) {
            Cell cell = rowHead.createCell(i);
            cell.setCellValue(head[i]);
            cell.setCellStyle(cellStyleHead);
        }
        /**
         * step 2.3:存储数据-待优化为反射共用注入
         */
        for (int i = 0; i < dataList.size(); i++) {
            // 创建行
            Row row = sheet.createRow(i + 1);
            // 获取数据
            SaleDataExcelDto dataEntity = dataList.get(i);
            // dataEntity存储到row
            entitySetRow(dataEntity, row, cellStyleCenter, cellStyleDouble, cellStyleDataFormat);
        }
        /**
         * step 2.4:追加备注
         */
        String remarks = "说明：\n" + "1、说明1111111111111111111111；\n" + "2、说明222222222222222222222222；\n" + "3、说明3333333333333333；\n";
        PoiExcelUtilsV0.setRemarks(cellStyleRemarks, sheet, remarks, dataList.size());
        /**
         * step 3:输出并关闭
         * 使用OutputStream,在Knife4j接口文档下载的文件打不开
         */
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            response.setContentType("application/vnd.ms-excel");
            String fileName = "测试导出模板.xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(outputStream);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void annotationExp() {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        PoiPerson d1 = new PoiPerson(1, "小郑", 28, "java", 6);
        PoiPerson d2 = new PoiPerson(2, "小2", 22, "前端", 1);
        List<PoiPerson> dataList = Arrays.asList(d1, d2);
        PoiExcelUtilsV2.export(response, "注解导出", dataList, PoiPerson.class);
    }

    /**
     * 实体数据赋值表格
     *
     * @param rowData
     * @param row
     * @param cellStyleCenter
     * @param cellStyleDouble
     * @param cellStyleDataFormat
     */
    void entitySetRow(SaleDataExcelDto rowData, Row row, CellStyle cellStyleCenter, CellStyle cellStyleDouble, CellStyle cellStyleDataFormat) {
        // 创建表格
        Cell lineCell = row.createCell(0);
        Cell saleTimeCell = row.createCell(1);
        Cell shopNoCell = row.createCell(2);
        Cell brandNameCell = row.createCell(3);
        Cell storeAmountCell = row.createCell(4);
        Cell storeOrderCell = row.createCell(5);
        Cell takeawayAmountCell = row.createCell(6);
        Cell takeawayOrderCell = row.createCell(7);
        // 风格设置
        lineCell.setCellStyle(cellStyleCenter);
        saleTimeCell.setCellStyle(cellStyleDataFormat);
        shopNoCell.setCellStyle(cellStyleCenter);
        brandNameCell.setCellStyle(cellStyleCenter);
        storeAmountCell.setCellStyle(cellStyleDouble);
        storeOrderCell.setCellStyle(cellStyleCenter);
        takeawayAmountCell.setCellStyle(cellStyleDouble);
        takeawayOrderCell.setCellStyle(cellStyleCenter);
        // 实体数据赋值表格
        lineCell.setCellValue(rowData.getLine());
        shopNoCell.setCellValue(rowData.getShopNo());
        brandNameCell.setCellValue(rowData.getBrandName());
    }
}
